<?php

namespace app\wechat\controller;

use app\wechat\controller\Openid;
use EasyWeChat\Kernel\Messages\Media;
use EasyWeChat\Kernel\Messages\News;
use EasyWeChat\Kernel\Messages\NewsItem;
use EasyWeChat\Kernel\Messages\Text;
use Pheanstalk\Pheanstalk;
use think\Db;
use think\Request;
use think\facade\Log;

// 客服消息相关
class Customer
{

    public $openPlatform;
    public $openidRedis;

    public function __construct()
    {
        $this->openPlatform = app('wechat.open_platform');
        $this->openidRedis = new Openid();
    }

    // 通过appid获取公众号实例
    public function get_official_account($appid)
    {
        $authinfo = $this->openPlatform->getAuthorizer($appid)['authorization_info'];
        $authtoken = $authinfo['authorizer_refresh_token'];
        $officialAccount = $this->openPlatform->officialAccount($appid, $authtoken);
        return $officialAccount;
    }

    // 获取全部素材id
    public function get_media_id(Request $request)
    {
        $appid = $request->post('appid');
        $type = $request->post('type');
        $page = $request->post('page');

        $offset = ($page - 1) * 10;
        $count = 10;
        $officialAccount = $this->get_official_account($appid);
        $material_list = $officialAccount->material->list($type, $offset, $count);

        return json($material_list);
    }

    // 发送文本客服消息任务
    public function send_text_msg_schedule(Request $request)
    {
        $res = '';

        // 获取参数
        $appid = $request->post('appid');
        $text = $request->post('text');
        $send_type = $request->post('send_type');
        $test_openid = $request->post('test_openid');
        $send_date = $request->post('send_date');

        // 判断发送类型
        switch ($send_type) {
            case 'send_test':
                if ($test_openid != '') {
                    $res = $this->send_cus_msg($appid, $test_openid, $text, 'text');
                }
                break;
            case 'send_now':
                $res = $this->send_async($appid, $text, 'text');
                break;
            case 'send_delay':
                if ($send_date != '') {
                    $delay = $send_date - time();
                    $res = $this->send_async($appid, $text, 'text', $delay);
                }
                break;
        }

        return $res;
    }

    // 发送素材客服消息任务
    public function send_media_msg_schedule(Request $request)
    {
        $res = '';

        // 获取参数
        $appid = $request->post('appid');
        $media_id = $request->post('media_id');
        $media_type = $request->post('media_type');
        $send_type = $request->post('send_type');
        $test_openid = $request->post('test_openid');
        $send_date = $request->post('send_date');

        $data['meida_id'] = $media_id;
        $data['media_type'] = $media_type;

        // 判断发送类型
        switch ($send_type) {
            case 'send_test':
                if ($test_openid != '') {
                    $res = $this->send_cus_msg($appid, $test_openid, $data, 'media');
                }
                break;
            case 'send_now':
                $res = $this->send_async($appid, $data, 'media');
                break;
            case 'send_delay':
                if ($send_date != '') {
                    $delay = $send_date - time();
                    $res = $this->send_async($appid, $data, 'media', $delay);
                }
                break;
        }

        return $res;
    }

    // 发送图片链接客服消息任务
    public function send_img_url_msg_schedule(Request $request)
    {
        $res = '';

        // 获取参数
        $appid = $request->post('appid');
        $items = $request->post('items');
        $send_type = $request->post('send_type');
        $test_openid = $request->post('test_openid');
        $send_date = $request->post('send_date');

        // 判断发送类型
        switch ($send_type) {
            case 'send_test':
                if ($test_openid != '') {
                    $res = $this->send_cus_msg($appid, $test_openid, $items, 'image');
                }
                break;
            case 'send_now':
                $res = $this->send_async($appid, $items, 'image');
                break;
            case 'send_delay':
                if ($send_date != '') {
                    $delay = $send_date - time();
                    $res = $this->send_async($appid, $items, 'image', $delay);
                }
                break;
        }

        return $res;
    }

    // 测试发送客服消息
    public function send_cus_msg($appid, $openid, $data, $type = 'text')
    {
        if ($type == 'media') {
            $msg = new Media($data['meida_id'], $data['media_type']);
        } elseif ($type == 'image') {
            $msg = $this->handleItems($data);
        } else {
            $msg = new Text($data);
        }
        $officialAccount = $this->get_official_account($appid);
        $result = $officialAccount->customer_service->message($msg)->to($openid)->send();
        return json($result);
    }

    // 异步发送文本客服消息
    public function send_async($appid, $data, $type = 'text', $delay = 0)
    {
        $pheanstalk = new Pheanstalk('127.0.0.1');

        $openid_list = $this->openidRedis->get_set($appid);
        $this->openidRedis->del_set($appid);

        $_data = array(
            'type' => $type,
            'data' => $data,
            'appid' => $appid,
            'openid_list' => $openid_list,
        );

        $job = $pheanstalk->useTube('customer')->put(json_encode($_data), 2, $delay, 60);

        if ($delay != 0) {
            Log::record('job_id: ' . $job . ', acc_id: ' . $appid);
            $data = ['job_id' => $job, 'acc_id' => $appid, 'delay' => $delay + time()];
            $res = Db::table('task')->insert($data);
            if ($res === 1) {
                return 'ok';
            } else {
                return 'error';
            }
        }

        return 'ok';
    }

    // 处理图文消息
    public function handleItems($items)
    {
        $new = array();
        foreach ($items as $item) {
            $new_item = new NewsItem([
                'title' => $item['title'],
                'description' => '',
                'url' => $item['url'],
                'image' => $item['image'],
            ]);
            array_push($new, $new_item);
        }

        return new News($new);
    }

    // 发送客服消息
    public function test_send($appid, $openid, $msg)
    {
        $officialAccount = $this->get_official_account($appid);
        $result = $officialAccount->customer_service->message($msg)->to($openid)->send();
        return json($result);
    }

}
